namespace BassettData.Robots
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// Defines a world in which the robots can roam.
    /// </summary>
    public class World
    {
        /// <summary>
        /// Lazily instantiates the World singleton.
        /// </summary>
        /// <remarks>
        /// See http://geekswithblogs.net/BlackRabbitCoder/archive/2010/05/19/c-system.lazylttgt-and-the-singleton-design-pattern.aspx
        /// </remarks>
        private static readonly Lazy<World> instance = new Lazy<World>(() => World.Default);

        /// <summary>
        /// Prevents a default instance of the World class from being created.
        /// </summary>
        private World()
        {
            BeeperLocations = new Dictionary<Location, int>();
            EastWestWalls = new List<EastWestWallLocation>();
            NorthSouthWalls = new List<NorthSouthWallLocation>();
        }

        /// <summary>
        /// Gets the instance.
        /// </summary>
        /// <value>The instance.</value>
        public static World Instance
        {
            get
            {
                return instance.Value;
            }
        }

        /// <summary>
        /// Gets or sets the number of streets.
        /// </summary>
        /// <value>The number of streets.</value>
        public int NumberOfStreets { get; set; }

        /// <summary>
        /// Gets or sets the number of avenues.
        /// </summary>
        /// <value>The number of avenues.</value>
        public int NumberOfAvenues { get; set; }

        /// <summary>
        /// Gets the beeper locations.
        /// </summary>
        /// <value>The beeper locations.</value>
        public Dictionary<Location, int> BeeperLocations { get; private set; }

        /// <summary>
        /// Gets the east-west walls.
        /// </summary>
        /// <value>The east-west walls.</value>
        public List<EastWestWallLocation> EastWestWalls { get; private set; }

        /// <summary>
        /// Gets the north-south walls.
        /// </summary>
        /// <value>The north-south walls.</value>
        public List<NorthSouthWallLocation> NorthSouthWalls { get; private set; }

        /// <summary>
        /// Gets an empty world with ten streets and ten avenues, 
        /// no walls and no beepers.
        /// </summary>
        private static World Default
        {
            get
            {
                return new World
                {
                    NumberOfStreets = 10,
                    NumberOfAvenues = 10
                };
            }
        }

        /// <summary>
        /// Reads the world from the given file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        public static void ReadWorld(string fileName)
        {
            WorldReader reader = new WorldReader();
            reader.ReadFromFile(fileName);
        }
    }
}
